﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CaoNiMaCoolPad
{
    public partial class StartForm : Form
    {
        private const int c_BufferSize = 4096;

        private readonly Form1 detailForm = new Form1();

        public StartForm()
        {
            InitializeComponent();
        }

        private void selectFileButton_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                detailForm.Items = ReadTblFile(openFileDialog1.FileName);
                this.Hide();
                detailForm.FormClosed += detailForm_FormClosed;
                detailForm.Show();
            }
        }

        void detailForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Close();
        }



        private static IList<string> ReadTblFile(string fileName)
        {

            using (BufferedStream fs = new BufferedStream(new FileStream(fileName, FileMode.Open)))
            {
                IList<string> list = new List<string>((int)(fs.Length * 800 / 166912));

                int time = Environment.TickCount;

                byte[] remainingPart = null;//上一次读取时，缓冲区的末尾的剩余字节。这些字节应该这次缓冲区的开头字节合并。如果为null，则不必合并。
                byte[] buffer = new byte[c_BufferSize];

                while (fs.Position < fs.Length)
                {
                    fs.Read(buffer, 0, c_BufferSize);

                    int dataStart;//即数据的开始
                    int dataEnd = -1;//即数据的结尾
                    if (remainingPart != null)
                    {
                        dataEnd = Utility.IndexOf4Zero(buffer);
                        if (dataEnd > -1)
                        {
                            byte[] whole = new byte[dataEnd + remainingPart.Length];
                            Array.Copy(remainingPart, whole, remainingPart.Length);
                            Array.Copy(buffer, 0, whole, remainingPart.Length, dataEnd);
                            list.Add(FindStringPresentation(whole, 0, whole.Length));
                            remainingPart = null;
                        }
                        else//整段缓冲区都是数据
                        {
                            dataEnd = c_BufferSize;

                            byte[] whole = new byte[dataEnd + remainingPart.Length];
                            Array.Copy(remainingPart, whole, remainingPart.Length);
                            Array.Copy(buffer, 0, whole, remainingPart.Length, dataEnd);
                            remainingPart = whole;
                        }
                    }

                    while (dataEnd < c_BufferSize)
                    {
                        for (dataStart = dataEnd + 1; dataStart < c_BufferSize; dataStart++)
                            if (buffer[dataStart] != 0)//不是0的位置就是数据开始的地方
                                break;

                        dataEnd = Utility.IndexOf4Zero(buffer, dataStart + 1);//是0的位置就是数据结束的地方

                        //dataStart和dataEnd不可能都等于c_BufferSize。
                        //如果dataStart==c_BufferSize，说明有一段数据刚好在缓冲区最后位置结束，即最后几位都是0。

                        if (dataStart < c_BufferSize && dataEnd == -1)//有一段疑似未结束的数据，
                        {
                            remainingPart = new byte[c_BufferSize - dataStart];
                            Array.Copy(buffer, dataStart, remainingPart, 0, remainingPart.Length);//那就把它复制到remainingPart里。
                            break;
                        }
                        else if (dataStart < c_BufferSize && dataStart != -1)
                        {
                            if (dataEnd - dataStart > 3)
                                list.Add(FindStringPresentation(buffer, dataStart, dataEnd - dataStart));
                        }
                        else
                            break;
                    }
                    //Debug.WriteLine("完成一次缓冲");
                    //return;
                }
                Debug.WriteLine(Environment.TickCount - time);
                return list;
            }
        }

        private static string FindStringPresentation(byte[] bytes, int index, int count)
        {
            try
            {
                string result;
                if (count == 21 && Utility.TryParseTime(bytes, index, out result))
                    return result;
                if (ZeroNumber(bytes, index, count) > count / 2.0)
                    return Utility.ByteArrayToString(bytes, index, count);
                else
                    return Utility.ParseUnicode(bytes, index, count);
            }
            catch
            {
                return Utility.ParseUnicode(bytes, index, count);
            }
        }

        private static int ZeroNumber(byte[] bytes, int index, int count)
        {
            int number = 0;
            for (int i = 0; index + i < bytes.Length && i < count; i++)
                if (bytes[index + i] == 0)
                    number++;
            return number;
        }
    }
}
